#pragma once

#include "../config.h"
#include "../opcode.h"

bool IsRunning();
void CloseServer();

class Gateway;

enum LoginResult
{
	LOGINRESULT_SUCCESS,
	LOGINRESULT_USER_EXIST,
};

enum LogoutResult
{
	LOGOUTRESULT_SUCCESS,
	LOGOUTRESULT_USER_NOT_EXIST,
	LOGOUTRESULT_USER_NOT_MATCH,
};

#define INSTALL_EPOLL_MAP(socket, connection)	(m_sockets.insert(std::make_pair(socket, connection)))

class Epoll : public Thread
{
	typedef std::map<int, Connection*>  SocketMap;

	friend class SingleTon<Epoll>;

public:

	Epoll(){}
	virtual ~Epoll();

	void Init(uint16 eventSize, int listenfd);
	
	virtual int _Prepare(){ return 0; }
	virtual int _Finish() { return 0; }
	virtual int _Kernel();

	void PushGateway(Connection* gateway);

private:

	void Handle();

	list<Connection*>	m_gateways;
	Mutex	m_mutex;

private:

	uint16	m_eventSize;

	int		m_listenfd;
	int		m_epfd;

#ifdef WIN32
	fd_set  m_writeSet;
	fd_set  m_readSet;
#elif defined(LINUX)
	epoll_event   m_ev;
	epoll_event** m_events;
#endif

	SocketMap	  m_sockets;
};

class GateServer : public Connection
{
	friend class GetSocketData;
	friend class SingleTon<GateServer>;
	
	typedef map<string, Gateway*> LoginMap;

	GateServer();

public:

	virtual ~GateServer();

	void Init(vector<string>& configs);
	void Load();

	virtual int Update();
	virtual void ClosePacket(){}
	virtual void HandleSendSocket(){}
	virtual void HandleRecvSocket(){}

	virtual bool Accept();

	LoginResult		Login(const string& uid, Gateway* gateway);
	LogoutResult	Logout(const string& uid, Gateway* gateway);
	void			Kickout(const string& uid);
	
	void PushGateway(Gateway* gateway);

private:

	Def			m_def;
	LoginMap	m_loginMap;

	list<Gateway*>	m_gateways;
	list<Gateway*>	m_pendingGateways;
	Epoll			m_epoll;
};

#define sGateServer  SingleTon<GateServer>::Instance()